﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.LightSwitch;
using Microsoft.LightSwitch.Threading;

namespace LightSwitchApplication.UserCode
{
    /* 
     Private Sub Export_Execute()

    Dim props As New List(Of String)()
 
    ' Only export storage properties
    For Each prop In Me.Customer.SelectedItem.Details.Properties.All.OfType(Of Details.IEntityStorageProperty)()
        props.Add(prop.Name)
    Next
    GeneralImportExport.EntityImportExport.PromptAndExportEntities(Me.DataWorkspace.ApplicationData.Customers, props.ToArray())
End Sub
The import button prompts the user first and then deletes all existing customers in the database. Next, it calls PromptAndImportEntities() to import new customers into the entity set specified, in this case, the Customers entity set.

Private Sub Import_Execute()

    If Me.ShowMessageBox("This will delete and re-import all Customers.  Do you want to continue?", "Continue?", MessageBoxOption.YesNo) = Windows.MessageBoxResult.Yes Then
        For Each cust As Customer In Me.DataWorkspace.ApplicationData.Customers
            cust.Delete()
        Next
        GeneralImportExport.EntityImportExport.PromptAndImportEntities(Me.DataWorkspace.ApplicationData.Customers)
        Me.Refresh()
    End 
     */

    /// <summary>
    /// Import and Exports collections of entity to csv. Code from blogs.msdn.com -> changed array to IList
    /// </summary>
    public static class ImportExportHelper
    {
        // change headers and data to IDictonary
        private static void ImportSingle(IEntitySet entitySetToCreateIn, IList<string> headers, IList<string> data)
        {
            // Create the new entity
            IEntityObject newEntity = entitySetToCreateIn.AddNew();

            Microsoft.LightSwitch.Details.IEntityProperty currentProperty;
            object newValue;

            // Loop through all propertyNames from the first line of the file
            foreach (string item in headers)
            {
                try
                {
                    // Get the property from the new entity by name
                    currentProperty = newEntity.Details.Properties[item];
                }
                catch (ArgumentException)
                {
                    throw new InvalidOperationException(String.Format("A property named {0} does not exist on the entity named {1}.", item, newEntity.Details.Name));
                }

                try
                {
                    // Convert the value
                    newValue = Convert.ChangeType(data[headers.IndexOf(item)], currentProperty.PropertyType, null);

                    currentProperty.Value = newValue;
                }
                catch (System.FormatException)
                {
                    throw new InvalidOperationException(String.Format("The following line has an invalid value for property {0}.  Aborting the import.\nData: {1}", item, String.Join(",", data)));
                }
            }
        }

        private static void PerformImport(System.IO.FileInfo file, IEntitySet entitySetToCreateIn)
        {
            System.IO.StreamReader reader = file.OpenText();
            string inputLine = reader.ReadLine();

            // Get the property names from the first line of input
            IList<string> headers = inputLine.Split(',').Select(header => header.Trim()).ToList<string>();
            int count = headers.Count();
            IList<string> data;

            inputLine = reader.ReadLine();
            while (inputLine != null)
            {
                data = inputLine.Split(',').ToList<string>();

                // If the right number of data items were found, import the line
                if (data.Count() == count)
                {
                    ImportSingle(entitySetToCreateIn, headers, data);
                }
                else
                {
                    throw new InvalidOperationException(String.Format("Line not imported.  Invalid number of elements.  Data = [{0}].", inputLine));
                }
                inputLine = reader.ReadLine();
            }
            reader.Close();

            entitySetToCreateIn.Details.DataService.SaveChanges();
        }

        public static void PromptAndImportEntities(IEntitySet entitySetToCreateIn)
        {
            System.IO.FileInfo file = null;

            // OpenFileDialog() must be opened on the UI thread
            Dispatchers.Main.Invoke(() =>
            {
                System.Windows.Controls.OpenFileDialog dlg = new System.Windows.Controls.OpenFileDialog();
                dlg.Filter = "CSV Files (*.csv)|*.csv|Text Files (*.txt)|*.txt";

                if (dlg.ShowDialog() == true)
                {
                    file = dlg.File;
                }
            });

            if (file != null)
            {
                PerformImport(file, entitySetToCreateIn);
            }
        }

        private static void ExportSingle(System.IO.StreamWriter writer, IEntityObject entity, IList<string> properties)
        {
            List<string> stringArray = new List<string>();
            Microsoft.LightSwitch.Details.IEntityProperty currentProperty;

            // Write each property to the string array
            foreach (string prop in properties)
            {
                try
                {
                    // Get the property from the entity by name
                    currentProperty = entity.Details.Properties[prop];
                }
                catch (Exception)
                {
                    throw new InvalidOperationException(String.Format("A property named {0} does not exist on the entity named {1}.", prop, entity.Details.Name));
                }
                stringArray.Add(currentProperty.Value.ToString());
            }
            // Write the string array
            writer.WriteLine(String.Join(",", stringArray.ToArray()));
        }

        private static void PerformExport(System.IO.Stream file, IEnumerable entitiesToExport, IList<string> properties)
        {
            // Initialize a writer
            System.IO.StreamWriter writer = new System.IO.StreamWriter(file);
            writer.AutoFlush = true;

            // Write the header
            writer.WriteLine(String.Join(",", properties));

            // Export each entity separately
            foreach (IEntityObject entity in entitiesToExport)
            {
                ExportSingle(writer, entity, properties);
            }
        }

        public static void PromptAndExportEntities(IEnumerable entitiesToExport, IList<string> properties)
        {
            //            Dim stream As IO.Stream = Nothing
            System.IO.Stream stream = null;

            // SaveFileDialog() must be opened on the UI thread
            Dispatchers.Main.Invoke(() =>
            {
                System.Windows.Controls.SaveFileDialog dlg = new System.Windows.Controls.SaveFileDialog();
                dlg.Filter = "CSV Files (*.csv)|*.csv|Text Files (*.txt)|*.txt";
                dlg.DefaultExt = "csv";

                if (dlg.ShowDialog() == true)
                {
                    stream = dlg.OpenFile();
                }
            });

            if (stream != null)
            {
                PerformExport(stream, entitiesToExport, properties);

                // Need to close the file on the UI thread as well
                Dispatchers.Main.Invoke(() =>
                {
                    stream.Close();
                });

            }
        }
    }
}
